#include "mainwindow.h"
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QDebug>
#include <QPixmap>
#include <QMessageBox>
#include <QComboBox>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>
#include "./ui_mainwindow.h"
#include "config.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowTitle(WINDOW_TITLE);
    QStringList vPixelList = {
        "96x96",
        "QQVGA(160x120)",
        "QCIF(176x144)",
        "HQVGA(240x176)",
        "240x240",
        "QVGA(320x240)",
        "CIF(400x296)",
        "HVGA(480x320)",
        "VGA(640x480)",
        "SVGA(800x600)",
        "XGA(1024x768)",
        "HD(1280x720)",
        "SXGA(1280x1024)",
        "UXGA(1600x1200)",
    };
    ui->cbxPixel->addItems(vPixelList);
    RequestStatus();
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_btnStart_clicked()
{
    if (m_pvClient != nullptr) {
        return;
    }
    const QString sIPAddr = ui->txtAddr->text();
    if (sIPAddr.size() == 0) {
        QMessageBox::warning(this, "提示", "请输入IP地址");
        return;
    }
    const QString sURL = "http://" + sIPAddr + ":81/stream";
    QNetworkAccessManager *pvManager = new QNetworkAccessManager();
    QNetworkRequest vRequest;
    vRequest.setUrl(sURL);
    vRequest.setRawHeader("Connection", "Keep-Alive");
    vRequest.setRawHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0");
    m_pvClient = pvManager->get(vRequest);
    connect(m_pvClient, &QNetworkReply::readyRead, this, &MainWindow::readyRead);
}


void MainWindow::on_btnStop_clicked()
{
    if (m_pvClient != nullptr) {
        disconnect(m_pvClient);
        m_pvClient->abort();
        m_pvClient->deleteLater();
        m_pvClient = nullptr;
        m_buffer.clear();
    }
}

void MainWindow::ParseFrame(const QByteArray &vBuf)
{
    const QString sBodyKey = "\r\n\r\n";
    const QString sItemKey = "\r\n";
    const QString sLengthKey = "Content-Length";
    int nBodyIndex = vBuf.indexOf(sBodyKey);
    if (nBodyIndex <= 0) {
        return;
    }
    QString sHead = vBuf.mid(0, nBodyIndex);
    QStringList vHeadSplit = sHead.split(sItemKey);
    QMap<QString, QString> vHeadMap;
    for (const QString &vItem : vHeadSplit) {
        QStringList vItemSplit = vItem.split(": ");
        if (vItemSplit.size() == 2) {
            vHeadMap[vItemSplit[0]] = vItemSplit[1];
        }
    }
    uint32_t nLength = 0;
    if (vHeadMap.count(sLengthKey) > 0) {
        nLength = vHeadMap[sLengthKey].toUInt();
    }
    if (nLength == 0) {
        return;
    }
    QByteArray sBody = vBuf.mid(nBodyIndex + sBodyKey.size(), nLength);
    QPixmap vPixmap;
    if (!vPixmap.loadFromData(sBody)) {
        qDebug() << "Failed to load image";
        return;
    }
    QPixmap vImage = vPixmap.scaled(ui->lblVideo->width(), ui->lblVideo->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
    ui->lblVideo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    ui->lblVideo->setPixmap(vImage);
}

void MainWindow::RequestStatus()
{
    m_buffer.clear();
    const QString sIPAddr = ui->txtAddr->text();
    if (sIPAddr.size() == 0) {
        return;
    }
    const QString sUrl = "http://" + sIPAddr + "/status";
    qDebug() << sUrl;
    QNetworkAccessManager manager;
    QNetworkRequest vRequest;
    QNetworkReply *reply;
    vRequest.setUrl(QUrl(sUrl));
    vRequest.setRawHeader("Connection", "Keep-Alive");
    vRequest.setRawHeader("Cache-Control", "no-cache");
    vRequest.setRawHeader("Pragma", "no-cache");
    vRequest.setRawHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0");
    reply = manager.get(vRequest);
    QEventLoop loop;
    QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    loop.exec();
    if (reply->error() == QNetworkReply::NoError) {
        QString jsonString = reply->readAll();
        QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonString.toUtf8());
        if (!jsonDocument.isNull()) {
            if (jsonDocument.isObject()) {
                QJsonObject jsonObject = jsonDocument.object();
                int framesize = jsonObject["framesize"].toInt();
                ui->cbxPixel->setCurrentIndex(framesize);
            }
        }
    } else {
        qDebug() << "Error: " << reply->errorString();
    }
    reply->deleteLater();
}


void MainWindow::on_cbxPixel_currentIndexChanged(int index)
{
    static bool isFirstSend = true;
    if (isFirstSend) {
        isFirstSend = false;
        return;
    }
    const QString sIPAddr = ui->txtAddr->text();
    if (sIPAddr.size() == 0) {
        return;
    }
    const QString sUrl = "http://" + sIPAddr + "/control?var=framesize&val=" + QString::number(index);
    qDebug() << sUrl;
    QNetworkAccessManager manager;
    QNetworkRequest vRequest;
    QNetworkReply *reply;
    vRequest.setUrl(QUrl(sUrl));
    vRequest.setRawHeader("Connection", "Keep-Alive");
    vRequest.setRawHeader("Cache-Control", "no-cache");
    vRequest.setRawHeader("Pragma", "no-cache");
    vRequest.setRawHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0");
    reply = manager.get(vRequest);
    m_mutex.lock();
    m_buffer.clear();
    m_mutex.unlock();
    QEventLoop loop;
    QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    loop.exec();
    if (reply->error() != QNetworkReply::NoError) {
        qDebug() << "Error: " << reply->errorString();
    }
    reply->deleteLater();
}

void MainWindow::readyRead()
{
    if (m_pvClient == nullptr) {
        return;
    }
    m_mutex.lock();
    m_buffer.append(m_pvClient->readAll());
    m_mutex.unlock();
    const QString sStartKey = "Content-Type: image/jpeg\r\nContent-Length:";
    const QString sEndKey = "\r\n--123456789000000000000987654321\r\n";
    while (true) {
        int nStartPos = m_buffer.indexOf(sStartKey);
        if (nStartPos < 0) {
            break;
        }
        int nEndPos = m_buffer.indexOf(sEndKey, nStartPos);
        if (nEndPos < 0) {
            break;
        }
        nStartPos = m_buffer.indexOf("\r\n");
        if (nStartPos < 0) {
            break;
        }
        nEndPos += sEndKey.size();
        QByteArray vBuf = m_buffer.mid(nStartPos, nEndPos - nStartPos);
        if (vBuf.size() == 0) {
            continue;
        }
        ParseFrame(vBuf);
        m_mutex.lock();
        m_buffer = m_buffer.mid(nEndPos, m_buffer.size() - nEndPos);
        m_mutex.unlock();
    }
}
